package com.resrun.controller;

import com.resrun.enums.CertFormatEnum;
import com.resrun.enums.CertStateEnum;
import com.resrun.model.CACert;
import com.resrun.model.CARequest;
import com.resrun.service.cert.CAService;
import com.resrun.service.pojo.CertificateInfo;
import com.resrun.utils.CaUtil;
import com.resrun.utils.FileUtil;
import com.resrun.vo.base.Result;
import com.resrun.vo.request.*;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.StreamUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * CA证书
 *
 * @author hupan
 * @since 2024-01-25
 */
@Slf4j
@Validated
@RestController
@AllArgsConstructor
@RequestMapping("/cert")
public class CAController {

    private CAService caService;

    /**
     * 申请证书：
     *
     * @param request X500信息
     * @return Result
     */
    @PostMapping("/request")
    public Result<Void> request(@Valid @RequestBody final CARequestRequest request) {
        return caService.saveRequest(request);
    }

    /**
     * 申请列表
     *
     * @return Result
     */
    @GetMapping("/request/list")
    public Result<Void> requestList() {
        // 查询数据库证书申请列表

        return Result.ok();
    }

    /**
     * 申请审核
     *
     * @return Result
     */
    @PostMapping("/audit")
    public Result<Void> audit(final @Valid @RequestBody CAAuditRequest request) {
        return caService.audit(request);
    }

    /**
     * 生成证书
     *
     * @param request 生成参数
     * @return Result
     */
    @PostMapping("/generate")
    public Result<Void> generate(@Valid @RequestBody GenerateCertRequest request) {
        return caService.generate(request);
    }

    /**
     * 重新生成证书
     *
     * @param request 生成参数
     * @return Result
     */
    @PostMapping("/regenerate")
    public Result<Void> regenerate(@Valid @RequestBody ReGenerateCertRequest request) {
        return caService.regenerate(request);
    }

    /**
     * 下载证书
     *
     * @param request 下载参数
     */
    @PostMapping("/download")
    public void download(final HttpServletResponse response, @RequestBody final CertDownloadRequest request) {
        Result<CACert> certResult = caService.getCertById(request.getCertId());
        if (!certResult.isSuccess()) {
            log.error("下载证书失败：{}", certResult.getMessage());
            return;
        }

        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=cert.zip");
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream())) {
            CACert cert = certResult.getResult();
            File file = FileUtil.getPKCS12File(cert.getEncode());
            FileSystemResource fileSystemResource = new FileSystemResource(file);
            ZipEntry zipEntry = new ZipEntry(file.getName());
            zipEntry.setSize(fileSystemResource.contentLength());
            zipEntry.setTime(System.currentTimeMillis());

            zipOutputStream.putNextEntry(zipEntry);

            StreamUtils.copy(fileSystemResource.getInputStream(), zipOutputStream);
            zipOutputStream.closeEntry();
            zipOutputStream.finish();
        } catch (Exception e) {
            log.error("下载证书异常", e);
        }
    }

}
